home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / file-tra / rdist-6.1 / rdist-6 / rdist-6.1.0-linuxpl2 / src / message.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-16  |  17.8 KB  |  869 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char RCSid[] = 
  36. "$Id: message.c,v 6.21 1994/04/20 17:53:28 mcooper Exp $";
  37.  
  38. static char sccsid[] = "@(#)common.c";
  39.  
  40. static char copyright[] =
  41. "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  42.  All rights reserved.\n";
  43. #endif /* !lint */
  44.  
  45. /*
  46.  * Message handling functions for both rdist and rdistd.
  47.  */
  48.  
  49. #include "defs.h"
  50.  
  51. #define MSGBUFSIZ    32*1024
  52.  
  53. int            debug = 0;        /* Debugging level */
  54. int            nerrs = 0;        /* Number of errors */
  55. char               *tempfile = NULL;    /* Name of temporary file */
  56.  
  57. /*
  58.  * Message Types
  59.  */
  60. MSGTYPE msgtypes[] = {
  61.     { MT_CHANGE,    "change" },
  62.     { MT_INFO,    "info" },
  63.     { MT_NOTICE,    "notice" },
  64.     { MT_NERROR,    "nerror" },
  65.     { MT_FERROR,    "ferror" },
  66.     { MT_WARNING,    "warning" },
  67.     { MT_VERBOSE,    "verbose" },
  68.     { MT_ALL,    "all" },
  69.     { MT_DEBUG,    "debug" },
  70.     { 0 },
  71. };
  72.  
  73. static void msgsendstdout(), msgsendfile(), msgsendsyslog(), 
  74.     msgsendnotify();
  75.  
  76. /*
  77.  * Message Facilities
  78.  */
  79. MSGFACILITY msgfacility[] = {
  80.     { MF_STDOUT,    "stdout",    msgsendstdout },
  81.     { MF_FILE,    "file",        msgsendfile },
  82.     { MF_SYSLOG,    "syslog",    msgsendsyslog },
  83.     { MF_NOTIFY,    "notify",    msgsendnotify },
  84.     { 0 },
  85. };
  86.  
  87. /*
  88.  * Print message logging usage message
  89.  */
  90. extern void msgprusage()
  91. {
  92.     register int i, x;
  93.  
  94.     (void) fprintf(stderr, "\nWhere <msgopt> is of form\n");
  95.     (void) fprintf(stderr, 
  96.        "\t<facility1>=<type1>,<type2>,...:<facility2>=<type1>,<type2>...\n");
  97.  
  98.     (void) fprintf(stderr, "Valid <facility> names:");
  99.  
  100.     for (i = 0; msgfacility[i].mf_name; ++i)
  101.         (void) fprintf(stderr, " %s", msgfacility[i].mf_name);
  102.  
  103.     (void) fprintf(stderr, "\nValid <type> names:");
  104.     for (x = 0; msgtypes[x].mt_name; ++x)
  105.         (void) fprintf(stderr, " %s", msgtypes[x].mt_name);
  106.  
  107.     (void) fprintf(stderr, "\n");
  108. }
  109.  
  110. /*
  111.  * Print enabled message logging info
  112.  */
  113. extern void msgprconfig()
  114. {
  115.     register int i, x;
  116.     static char buf[MSGBUFSIZ];
  117.  
  118.     debugmsg(DM_MISC, "Current message logging config:");
  119.     for (i = 0; msgfacility[i].mf_name; ++i) {
  120.         (void) sprintf(buf, "    %s=", msgfacility[i].mf_name);
  121.         for (x = 0; msgtypes[x].mt_name; ++x)
  122.             if (IS_ON(msgfacility[i].mf_msgtypes, 
  123.                   msgtypes[x].mt_type)) {
  124.                 if (x > 0)
  125.                     (void) strcat(buf, ",");
  126.                 (void) strcat(buf, msgtypes[x].mt_name);
  127.             }
  128.         debugmsg(DM_MISC, "%s", buf);
  129.     }
  130.  
  131. }
  132.  
  133. /*
  134.  * Get the Message Facility entry "name"
  135.  */
  136. static MSGFACILITY *getmsgfac(name)
  137.     char *name;
  138. {
  139.     register int i;
  140.  
  141.     for (i = 0; msgfacility[i].mf_name; ++i)
  142.         if (strcasecmp(name, msgfacility[i].mf_name) == 0)
  143.             return(&msgfacility[i]);
  144.  
  145.     return((MSGFACILITY *) NULL);
  146. }
  147.  
  148. /*
  149.  * Get the Message Type entry named "name"
  150.  */
  151. static MSGTYPE *getmsgtype(name)
  152.     char *name;
  153. {
  154.     register int i;
  155.  
  156.     for (i = 0; msgtypes[i].mt_name; ++i)
  157.         if (strcasecmp(name, msgtypes[i].mt_name) == 0)
  158.             return(&msgtypes[i]);
  159.  
  160.     return((MSGTYPE *) NULL);
  161. }
  162.  
  163. /*
  164.  * Set Message Type information for Message Facility "msgfac" as
  165.  * indicated by string "str".
  166.  */
  167. static char *setmsgtypes(msgfac, str)
  168.     MSGFACILITY *msgfac;
  169.     char *str;
  170. {
  171.     static char ebuf[BUFSIZ];
  172.     register char *cp;
  173.     register char *strptr, *word;
  174.     register MSGTYPE *mtp;
  175.  
  176.     /*
  177.      * MF_SYSLOG is the only supported message facility for the server
  178.      */
  179.     if (isserver && (msgfac->mf_msgfac != MF_SYSLOG && 
  180.              msgfac->mf_msgfac != MF_FILE)) {
  181.         (void) sprintf(ebuf,
  182.         "The \"%s\" message facility cannot be used by the server.",
  183.                    msgfac->mf_name);
  184.         return(ebuf);
  185.     }
  186.  
  187.     strptr = str;
  188.  
  189.     /*
  190.      * Do any necessary Message Facility preparation
  191.      */
  192.     switch(msgfac->mf_msgfac) {
  193.     case MF_FILE:
  194.         /*
  195.          * The MF_FILE string should look like "<file>=<types>".
  196.          */
  197.         if ((cp = strchr(strptr, '=')) == NULL)
  198.             return(
  199.                "No file name found for \"file\" message facility");
  200.         *cp++ = CNULL;
  201.  
  202.         if ((msgfac->mf_fptr = fopen(strptr, "w")) == NULL)
  203.             fatalerr("Cannot open log file for writing: %s: %s.",
  204.                  strptr, SYSERR);
  205.         msgfac->mf_filename = strdup(strptr);
  206.  
  207.         strptr = cp;
  208.         break;
  209.  
  210.     case MF_NOTIFY:
  211.         break;
  212.  
  213.     case MF_STDOUT:
  214.         msgfac->mf_fptr = stdout;
  215.         break;
  216.  
  217.     case MF_SYSLOG:
  218. #if defined(LOG_OPTS)
  219. #if    defined(LOG_FACILITY)
  220.         openlog(progname, LOG_OPTS, LOG_FACILITY);
  221. #else
  222.         openlog(progname, LOG_OPTS);
  223. #endif    /* LOG_FACILITY */
  224. #endif    /* LOG_OPTS */
  225.         break;
  226.     }
  227.  
  228.     /*
  229.      * Parse each type word
  230.      */
  231.     msgfac->mf_msgtypes = 0;    /* Start from scratch */
  232.     while (strptr) {
  233.         word = strptr;
  234.         if (cp = strchr(strptr, ','))
  235.             *cp++ = CNULL;
  236.         strptr = cp;
  237.  
  238.         if (mtp = getmsgtype(word)) {
  239.             msgfac->mf_msgtypes |= mtp->mt_type;
  240.             /*
  241.              * XXX This is really a kludge until we add real
  242.              * control over debugging.
  243.              */
  244.             if (!debug && isserver && 
  245.                 strcasecmp(word, "debug") == 0)
  246.                 debug = DM_ALL;
  247.         } else {
  248.             (void) sprintf(ebuf, "Message type \"%s\" is invalid.",
  249.                        word);
  250.             return(ebuf);
  251.         }
  252.     }
  253.  
  254.     return((char *) NULL);
  255. }
  256.  
  257. /*
  258.  * Parse a message logging option string
  259.  */
  260. extern char *msgparseopts(msgstr, doset)
  261.     char *msgstr;
  262.     int doset;
  263. {
  264.     static char ebuf[BUFSIZ], msgbuf[MSGBUFSIZ];
  265.     register char *cp, *optstr;
  266.     register char *word;
  267.     MSGFACILITY *msgfac;
  268.  
  269.     if (msgstr == NULL)
  270.         return("NULL message string");
  271.  
  272.     /* strtok() is harmful */
  273.     (void) strcpy(msgbuf, msgstr);
  274.  
  275.     /*
  276.      * Each <facility>=<types> list is seperated by ":".
  277.      */
  278.     for (optstr = strtok(msgbuf, ":"); optstr;
  279.          optstr = strtok((char *)NULL, ":")) {
  280.  
  281.         if ((cp = strchr(optstr, '=')) == NULL)
  282.             return("No '=' found");
  283.  
  284.         *cp++ = CNULL;
  285.         word = optstr;
  286.         if ((int)strlen(word) <= 0)
  287.             return("No message facility specified");
  288.         if ((int)strlen(cp) <= 0)
  289.             return("No message type specified");
  290.  
  291.         if ((msgfac = getmsgfac(word)) == NULL) {
  292.             (void) sprintf(ebuf, 
  293.                        "%s is not a valid message facility", 
  294.                        word);
  295.             return(ebuf);
  296.         }
  297.         
  298.         if (doset) {
  299.             char *mcp;
  300.  
  301.             if (mcp = setmsgtypes(msgfac, cp))
  302.                 return(mcp);
  303.         }
  304.     }
  305.  
  306.     if (isserver && debug) {
  307.         debugmsg(DM_MISC, "%s", getversion());
  308.         msgprconfig();
  309.     }
  310.  
  311.     return((char *) NULL);
  312. }
  313.  
  314. /*
  315.  * Send a message to facility "stdout".
  316.  * For rdistd, this is really the rdist client.
  317.  */
  318. static void msgsendstdout(msgfac, mtype, flags, msgbuf)
  319.     /*ARGSUSED*/
  320.     MSGFACILITY *msgfac;
  321.     int mtype;
  322.     int flags;
  323.     char *msgbuf;
  324. {
  325.     char cmd;
  326.  
  327.     if (isserver) {
  328.         if (rem_w < 0 || IS_ON(flags, MT_NOREMOTE))
  329.             return;
  330.  
  331.         cmd = CNULL;
  332.  
  333.         switch(mtype) {
  334.         case MT_NERROR:        cmd = C_ERRMSG;        break;
  335.         case MT_FERROR:        cmd = C_FERRMSG;    break;
  336.         case MT_NOTICE:        cmd = C_NOTEMSG;    break;
  337.         case MT_REMOTE:        cmd = C_LOGMSG;        break;
  338.         }
  339.  
  340.         if (cmd != CNULL)
  341.             (void) sendcmd(cmd, "%s", msgbuf);
  342.     } else {
  343.         switch(mtype) {
  344.         case MT_FERROR:
  345.         case MT_NERROR:
  346.             if (msgbuf && *msgbuf) {
  347.                 (void) fprintf(stderr, "%s\n", msgbuf);
  348.                 (void) fflush(stderr);
  349.             }
  350.             break;
  351.  
  352.         case MT_DEBUG:
  353.             /* 
  354.              * Only things that are strictly MT_DEBUG should
  355.              * be shown.
  356.              */
  357.             if (flags != MT_DEBUG)
  358.                 return;
  359.         case MT_NOTICE:
  360.         case MT_CHANGE:
  361.         case MT_INFO:
  362.         case MT_VERBOSE:
  363.         case MT_WARNING:
  364.             if (msgbuf && *msgbuf) {
  365.                 (void) printf("%s\n", msgbuf);
  366.                 (void) fflush(stdout);
  367.             }
  368.             break;
  369.         }
  370.     }
  371. }
  372.  
  373. /*
  374.  * Send a message to facility "syslog"
  375.  */
  376. static void msgsendsyslog(msgfac, mtype, flags, msgbuf)
  377.     /*ARGSUSED*/
  378.     MSGFACILITY *msgfac;
  379.     int mtype;
  380.     int flags;
  381.     char *msgbuf;
  382. {
  383.     int syslvl = 0;
  384.  
  385.     if (!msgbuf || !*msgbuf)
  386.         return;
  387.  
  388.     switch(mtype) {
  389. #if    defined(SL_NERROR)
  390.     case MT_NERROR:        syslvl = SL_NERROR;    break;
  391. #endif
  392. #if    defined(SL_FERROR)
  393.     case MT_FERROR:        syslvl = SL_FERROR;    break;
  394. #endif
  395. #if    defined(SL_WARNING)
  396.     case MT_WARNING:    syslvl = SL_WARNING;    break;
  397. #endif
  398. #if    defined(SL_CHANGE)
  399.     case MT_CHANGE:        syslvl = SL_CHANGE;    break;
  400. #endif
  401. #if    defined(SL_INFO)
  402.     case MT_SYSLOG:
  403.     case MT_VERBOSE:
  404.     case MT_INFO:        syslvl = SL_INFO;    break;
  405. #endif
  406. #if    defined(SL_NOTICE)
  407.     case MT_NOTICE:        syslvl = SL_NOTICE;    break;
  408. #endif
  409. #if    defined(SL_DEBUG)
  410.     case MT_DEBUG:        syslvl = SL_DEBUG;    break;
  411. #endif
  412.     }
  413.  
  414.     if (syslvl)
  415.         syslog(syslvl, "%s", msgbuf);
  416. }
  417.  
  418. /*
  419.  * Send a message to a "file" facility.
  420.  */
  421. static void msgsendfile(msgfac, mtype, flags, msgbuf)
  422.     /*ARGSUSED*/
  423.     MSGFACILITY *msgfac;
  424.     int mtype;
  425.     int flags;
  426.     char *msgbuf;
  427. {
  428.     if (msgfac->mf_fptr == NULL)
  429.         return;
  430.  
  431.     if (!msgbuf || !*msgbuf)
  432.         return;
  433.  
  434.     (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
  435.     (void) fflush(msgfac->mf_fptr);
  436. }
  437.  
  438. /*
  439.  * Same method as msgsendfile()
  440.  */
  441. static void msgsendnotify(msgfac, mtype, flags, msgbuf)
  442.     /*ARGSUSED*/
  443.     MSGFACILITY *msgfac;
  444.     int mtype;
  445.     int flags;
  446.     char *msgbuf;
  447. {
  448.     if (IS_ON(flags, MT_DEBUG))
  449.         return;
  450.  
  451.     if (!msgbuf || !*msgbuf)
  452.         return;
  453.  
  454.     if (!msgfac->mf_fptr) {
  455.         register char *cp;
  456.         char *getenv();
  457.  
  458.         /*
  459.          * Create and open a new temporary file
  460.          */
  461.         if ((cp = getenv("TMPDIR")) == (char *) NULL)
  462.             cp = _PATH_TMP;
  463.         tempfile = (char *) xmalloc(strlen(cp) + 1 + 
  464.                         strlen(_RDIST_TMP) + 2);
  465.         (void) sprintf(tempfile, "%s/%s", cp, _RDIST_TMP);
  466.  
  467.         msgfac->mf_filename = tempfile;
  468.         (void) mktemp(msgfac->mf_filename);
  469.         if ((msgfac->mf_fptr = fopen(msgfac->mf_filename, "w"))==NULL)
  470.             fatalerr("Cannot open notify file for writing: %s: %s.",
  471.                   msgfac->mf_filename, SYSERR);
  472.         debugmsg(DM_MISC, "Created notify temp file '%s'",
  473.              msgfac->mf_filename);
  474.     }
  475.  
  476.     if (msgfac->mf_fptr == NULL)
  477.         return;
  478.  
  479.     (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
  480.     (void) fflush(msgfac->mf_fptr);
  481. }
  482.  
  483. /*
  484.  * Insure currenthost is set to something reasonable.
  485.  */
  486. extern void checkhostname()
  487. {
  488.     static char mbuf[MAXHOSTNAMELEN];
  489.     char *cp;
  490.  
  491.     if (!currenthost) {
  492.         if (gethostname(mbuf, sizeof(mbuf)) == 0) {
  493.             if ((cp = strchr(mbuf, '.')) != NULL)
  494.                 *cp = CNULL;
  495.             currenthost = strdup(mbuf);
  496.         } else
  497.             currenthost = "(unknown)";
  498.     }
  499. }
  500.  
  501. /*
  502.  * Print a message contained in "msgbuf" if a level "lvl" is set.
  503.  */
  504. static void _message(flags, msgbuf)
  505.     int flags;
  506.     char *msgbuf;
  507. {
  508.     register int i, x;
  509.     register char *cp;
  510.     static char mbuf[2048];
  511.  
  512.     if (msgbuf && *msgbuf) {
  513.         /*
  514.          * Ensure no stray newlines are present
  515.          */
  516.         if (cp = strchr(msgbuf, '\n'))
  517.             *cp = CNULL;
  518.  
  519.         checkhostname();
  520.         if (strncmp(currenthost, msgbuf, strlen(currenthost)) == 0)
  521.             (void) strcpy(mbuf, msgbuf);
  522.         else
  523.             (void) sprintf(mbuf, "%s: %s", currenthost, msgbuf);
  524.     } else
  525.         (void) strcpy(mbuf, "");
  526.  
  527.     /*
  528.      * Special case for messages that only get
  529.      * logged to the system log facility
  530.      */
  531.     if (IS_ON(flags, MT_SYSLOG)) {
  532.         msgsendsyslog((MSGFACILITY *)NULL, MT_SYSLOG, flags, mbuf);
  533.         return;
  534.     }
  535.  
  536.     /*
  537.      * Special cases
  538.      */
  539.     if (isserver && IS_ON(flags, MT_REMOTE))
  540.         msgsendstdout((MSGFACILITY *)NULL, MT_REMOTE, flags, mbuf);
  541.     else if (isserver && IS_ON(flags, MT_NERROR))
  542.         msgsendstdout((MSGFACILITY *)NULL, MT_NERROR, flags, mbuf);
  543.     else if (isserver && IS_ON(flags, MT_FERROR))
  544.         msgsendstdout((MSGFACILITY *)NULL, MT_FERROR, flags, mbuf);
  545.     else if (isserver && IS_ON(flags, MT_NOTICE)) {
  546.         msgsendstdout((MSGFACILITY *)NULL, MT_NOTICE, flags, mbuf);
  547.         return;
  548.     }
  549.  
  550.     /*
  551.      * For each Message Facility, check each Message Type to see
  552.      * if the bits in "flags" are set.  If so, call the appropriate
  553.      * Message Facility to dispatch the message.
  554.      */
  555.     for (i = 0; msgfacility[i].mf_name; ++i)
  556.         for (x = 0; msgtypes[x].mt_name; ++x)
  557.             /* 
  558.              * XXX MT_ALL should not be used directly 
  559.              */
  560.             if (msgtypes[x].mt_type != MT_ALL &&
  561.                 IS_ON(flags, msgtypes[x].mt_type) &&
  562.                 IS_ON(msgfacility[i].mf_msgtypes,
  563.                   msgtypes[x].mt_type))
  564.                 (*msgfacility[i].mf_sendfunc)(&msgfacility[i],
  565.                                msgtypes[x].mt_type,
  566.                                   flags,
  567.                                   mbuf);
  568. }
  569.  
  570. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
  571. /*
  572.  * Varargs front-end to _message()
  573.  */
  574. extern void message(va_alist)
  575.     va_dcl
  576. {
  577.     static char buf[MSGBUFSIZ];
  578.     va_list args;
  579.     char *fmt;
  580.     int lvl;
  581.  
  582.     va_start(args);
  583.     lvl = (int) va_arg(args, int);
  584.     fmt = (char *) va_arg(args, char *);
  585.     va_end(args);
  586.  
  587.     (void) vsprintf(buf, fmt, args);
  588.  
  589.     _message(lvl, buf);
  590. }
  591. #endif    /* ARG_VARARGS */
  592.  
  593. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
  594. /*
  595.  * Stdarg front-end to _message()
  596.  */
  597. extern void message(int lvl, char *fmt, ...)
  598. {
  599.     static char buf[MSGBUFSIZ];
  600.     va_list args;
  601.  
  602.     va_start(args, fmt);
  603.     (void) vsprintf(buf, fmt, args);
  604.     va_end(args);
  605.  
  606.     _message(lvl, buf);
  607. }
  608. #endif    /* ARG_STDARG */
  609.  
  610.  
  611. #if    !defined(ARG_TYPE)
  612. /*
  613.  * Simple front-end to _message()
  614.  */
  615. /*VARARGS2*/
  616. extern void message(lvl, fmt, a1, a2, a3, a4, a5)
  617.     int lvl;
  618.     char *fmt;
  619. {
  620.     static char buf[MSGBUFSIZ];
  621.  
  622.     (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
  623.  
  624.     _message(lvl, buf);
  625. }
  626. #endif    /* !ARG_TYPE */
  627.  
  628. /*
  629.  * Display a debugging message
  630.  */
  631. static void _debugmsg(lvl, buf)
  632.     int lvl;
  633.     char *buf;
  634. {
  635.     if (IS_ON(debug, lvl))
  636.         _message(MT_DEBUG, buf);
  637. }
  638.  
  639. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
  640. /*
  641.  * Varargs front-end to _debugmsg()
  642.  */
  643. extern void debugmsg(va_alist)
  644.     va_dcl
  645. {
  646.     static char buf[MSGBUFSIZ];
  647.     va_list args;
  648.     char *fmt;
  649.     int lvl;
  650.  
  651.     va_start(args);
  652.     lvl = (int) va_arg(args, int);
  653.     fmt = (char *) va_arg(args, char *);
  654.     va_end(args);
  655.  
  656.     (void) vsprintf(buf, fmt, args);
  657.  
  658.     _debugmsg(lvl, buf);
  659. }
  660. #endif    /* ARG_VARARGS */
  661.  
  662. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
  663. /*
  664.  * Stdarg front-end to _debugmsg()
  665.  */
  666. extern void debugmsg(int lvl, char *fmt, ...)
  667. {
  668.     static char buf[MSGBUFSIZ];
  669.     va_list args;
  670.  
  671.     va_start(args, fmt);
  672.     (void) vsprintf(buf, fmt, args);
  673.     va_end(args);
  674.  
  675.     _debugmsg(lvl, buf);
  676. }
  677. #endif    /* ARG_STDARG */
  678.  
  679. #if    !defined(ARG_TYPE)
  680. /*
  681.  * Simple front-end to _debugmsg()
  682.  */
  683. /*VARARGS2*/
  684. extern void debugmsg(lvl, fmt, a1, a2, a3, a4, a5)
  685.     int lvl;
  686.     char *fmt;
  687. {
  688.     static char buf[MSGBUFSIZ];
  689.  
  690.     (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
  691.  
  692.     _debugmsg(lvl, buf);
  693. }
  694. #endif    /* ARG_TYPE */
  695.  
  696. /*
  697.  * Print an error message
  698.  */
  699. static void _error(msg)
  700.     char *msg;
  701. {
  702.     static char buf[MSGBUFSIZ];
  703.  
  704.     nerrs++;
  705.     buf[0] = CNULL;
  706.  
  707.     if (msg) {
  708.         if (isserver)
  709.             (void) sprintf(buf, "REMOTE ERROR: %s", msg);
  710.         else
  711.             (void) sprintf(buf, "LOCAL ERROR: %s", msg);
  712.     }
  713.  
  714.     _message(MT_NERROR, (buf[0]) ? buf : NULL);
  715. }
  716.  
  717. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
  718. /*
  719.  * Varargs frontend to _error()
  720.  */
  721. extern void error(va_alist)
  722.     va_dcl
  723. {
  724.     static char buf[MSGBUFSIZ];
  725.     va_list args;
  726.     char *fmt;
  727.  
  728.     buf[0] = CNULL;
  729.     va_start(args);
  730.     fmt = (char *) va_arg(args, char *);
  731.     if (fmt)
  732.         (void) vsprintf(buf, fmt, args);
  733.     va_end(args);
  734.  
  735.     _error((buf[0]) ? buf : NULL);
  736. }
  737. #endif    /* ARG_VARARGS */
  738.  
  739. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
  740. /*
  741.  * Stdarg frontend to _error()
  742.  */
  743. extern void error(char *fmt, ...)
  744. {
  745.     static char buf[MSGBUFSIZ];
  746.     va_list args;
  747.  
  748.     buf[0] = CNULL;
  749.     va_start(args, fmt);
  750.     if (fmt)
  751.         (void) vsprintf(buf, fmt, args);
  752.     va_end(args);
  753.  
  754.     _error((buf[0]) ? buf : NULL);
  755. }
  756. #endif    /* ARG_STDARG */
  757.  
  758. #if    !defined(ARG_TYPE)
  759. /*
  760.  * Simple frontend to _error()
  761.  */
  762. /*VARARGS1*/
  763. extern void error(fmt, a1, a2, a3, a4, a5, a6)
  764.     char *fmt;
  765. {
  766.     static char buf[MSGBUFSIZ];
  767.  
  768.     buf[0] = CNULL;
  769.     if (fmt)
  770.         (void) sprintf(buf, fmt, a1, a2, a3, a4, a5, a6);
  771.  
  772.     _error((buf[0]) ? buf : NULL);
  773. }
  774. #endif /* ARG_TYPE */
  775.  
  776. /*
  777.  * Display a fatal message
  778.  */
  779. static void _fatalerr(msg)
  780.     char *msg;
  781. {
  782.     static char buf[MSGBUFSIZ];
  783.  
  784.     ++nerrs;
  785.  
  786.     if (isserver)
  787.         (void) sprintf(buf, "REMOTE ERROR: %s", msg);
  788.     else
  789.         (void) sprintf(buf, "LOCAL ERROR: %s", msg);
  790.  
  791.     _message(MT_FERROR, buf);
  792.  
  793.     exit(nerrs);
  794. }
  795.  
  796. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
  797. /*
  798.  * Varargs front-end to _fatalerr()
  799.  */
  800. extern void fatalerr(va_alist)
  801.     va_dcl
  802. {
  803.     static char buf[MSGBUFSIZ];
  804.     va_list args;
  805.     char *fmt;
  806.  
  807.     va_start(args);
  808.     fmt = (char *) va_arg(args, char *);
  809.     (void) vsprintf(buf, fmt, args);
  810.     va_end(args);
  811.  
  812.     _fatalerr(buf);
  813. }
  814. #endif    /* ARG_VARARGS */
  815.  
  816. #if    defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
  817. /*
  818.  * Stdarg front-end to _fatalerr()
  819.  */
  820. extern void fatalerr(char *fmt, ...)
  821. {
  822.     static char buf[MSGBUFSIZ];
  823.     va_list args;
  824.  
  825.     va_start(args, fmt);
  826.     (void) vsprintf(buf, fmt, args);
  827.     va_end(args);
  828.  
  829.     _fatalerr(buf);
  830. }
  831. #endif    /* ARG_STDARG */
  832.  
  833. #if    !defined(ARG_TYPE)
  834. /*
  835.  * Simple front-end to _fatalerr()
  836.  */
  837. /*VARARGS1*/
  838. extern void fatalerr(fmt, a1, a2, a3, a4, a5)
  839.     char *fmt;
  840. {
  841.     static char buf[MSGBUFSIZ];
  842.  
  843.     (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
  844.  
  845.     _fatalerr(buf);
  846. }
  847. #endif    /* !ARG_TYPE */
  848.  
  849. /*
  850.  * Get the name of the file used for notify.
  851.  * A side effect is that the file pointer to the file
  852.  * is closed.  We assume this function is only called when
  853.  * we are ready to read the file.
  854.  */
  855. extern char *getnotifyfile()
  856. {
  857.     register int i;
  858.  
  859.     for (i = 0; msgfacility[i].mf_name; i++)
  860.         if (msgfacility[i].mf_msgfac == MF_NOTIFY &&
  861.             msgfacility[i].mf_fptr) {
  862.             (void) fclose(msgfacility[i].mf_fptr);
  863.             msgfacility[i].mf_fptr = NULL;
  864.             return(msgfacility[i].mf_filename);
  865.         }
  866.  
  867.     return((char *) NULL);
  868. }
  869.